package org.snare.alumni.modules.admin.card.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.snare.alumni.modules.admin.card.dto.CardDTO;
import org.snare.alumni.modules.admin.card.dto.CardSameVO;
import org.snare.alumni.modules.admin.card.entity.CardEntity;
import org.snare.alumni.modules.admin.card.mapper.CardMapper;
import org.snare.alumni.modules.admin.card.service.api.CardService;
import org.snare.alumni.modules.admin.student.entity.StudentEntity;
import org.snare.alumni.modules.admin.student.mapper.StudentMapper;
import org.snare.community.modules.admin.account.dto.AccountInfo;
import org.snare.community.modules.admin.account.entity.SnsAccountEntity;
import org.snare.community.modules.admin.account.mapper.SnsAccountMapper;
import org.snare.community.modules.admin.account.service.api.SnsAccountService;
import org.snare.spider.cobweb.crm.user.entity.CrmUserEntity;
import org.snare.spider.cobweb.crm.user.mapper.CrmUserMapper;
import org.snare.spider.cobweb.oss.dto.FileUploadDTO;
import org.snare.spider.common.base.Limit;
import org.snare.spider.common.exception.BusinessException;
import org.snare.spider.common.utils.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;


@Service
@RequiredArgsConstructor
public class CardServiceImpl implements CardService {

    private final SnsAccountMapper snsAccountMapper;

    private final SnsAccountService snsAccountService;

    private final CardMapper cardMapper;

    private final CrmUserMapper crmUserMapper;

    private final StudentMapper studentMapper;

    @Override
    public IPage<CardDTO> page(CardDTO params, Limit limit) {
        MPJLambdaWrapper<CardEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(CardEntity.class)
                .select(CrmUserEntity::getRealName)
                .leftJoin(CrmUserEntity.class, CrmUserEntity::getId, CardEntity::getUid)
                .eq(StringUtils.isNotBlank(params.getPhone()), CardEntity::getPhone, params.getPhone())
                .like(StringUtils.isNotBlank(params.getName()), CrmUserEntity::getRealName, params.getName())
                .eq(StringUtils.isNotBlank(params.getStatus()), CardEntity::getStatus, params.getStatus())
                .orderByDesc(CardEntity::getStatus, CardEntity::getCreateTime);
        IPage<CardDTO> page = cardMapper.selectJoinPage(limit.page(), CardDTO.class, wrapper);
        for (CardDTO item : page.getRecords()) {
            item.setStudentList(new LambdaQueryChainWrapper<>(studentMapper)
                    .eq(StudentEntity::getUid, item.getUid())
                    .orderByDesc(StudentEntity::getGraduationYear).list()
            );
        }
        return page;
    }

    @Override
    public void add(CardDTO params) {
        CardEntity cardEntity = null;
        LambdaQueryWrapper<CardEntity> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getUid())) {
            wrapper.eq(CardEntity::getUid, params.getUid());
        } else {
            wrapper.eq(CardEntity::getPhone, params.getPhone());
        }
        cardEntity = cardMapper.selectOne(wrapper);

        if (cardEntity != null && (Arrays.asList("1", "2").contains(cardEntity.getStatus()))) {
            throw new BusinessException("您已申请，请忽重复申请");
        }

        CardEntity entity = BeanUtils.copy(params, CardEntity.class);
        if (CollectionUtils.isNotEmpty(params.getImgList())) {
            entity.setImages(JSON.toJSONString(params.getImgList()));
        }

        if (cardEntity == null) {
            entity.setStatus("0");
            cardMapper.insert(entity);
        } else {
            entity.setStatus("1");
            cardMapper.updateById(entity);
        }

    }

    @Override
    public void edit(CardDTO params) {
        CardEntity entity = BeanUtils.copy(params, CardEntity.class);
        if (CollectionUtils.isNotEmpty(params.getImgList())) {
            entity.setImages(JSON.toJSONString(params.getImgList()));
        }
        cardMapper.updateById(entity);
        new LambdaUpdateChainWrapper<>(crmUserMapper)
                .set(CrmUserEntity::getRealName, params.getName())
                .set(CrmUserEntity::getPhone, params.getPhone())
                .eq(CrmUserEntity::getId, params.getUid()).update();
    }

    @Override
    public void delete(String id) {
        cardMapper.deleteById(id);
    }

    @Override
    public CardDTO detail(String id, String uid) {
        if (StringUtils.isBlank(id) && StringUtils.isBlank(uid)) {
            throw new BusinessException("参数错误");
        }
        MPJLambdaWrapper<CardEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(CardEntity.class)
                .select(CrmUserEntity::getRealName)
                .leftJoin(CrmUserEntity.class, CrmUserEntity::getId, CardEntity::getUid)
                .eq(StringUtils.isNotBlank(id), CardEntity::getId, id)
                .eq(StringUtils.isNotBlank(uid), CardEntity::getUid, uid);
        CardDTO cardDTO = cardMapper.selectJoinOne(CardDTO.class, wrapper);
        cardDTO.setStudentList(new LambdaQueryChainWrapper<>(studentMapper)
                .eq(StudentEntity::getUid, uid).orderByDesc(StudentEntity::getGraduationYear).list());
        return cardDTO;
    }

    @Override
    public void approve(CardDTO params) {
        if (StringUtils.isBlank(params.getId()) || params.getStatus() == null) {
            throw new BusinessException("参数错误");
        }
        CardEntity cardEntity = new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getId, params.getId()).one();
        if (cardEntity == null) {
            throw new BusinessException("数据不存在,请重试");
        }
        new LambdaUpdateChainWrapper<>(cardMapper)
                .set(CardEntity::getOpinion, params.getOpinion())
                .set(CardEntity::getStatus, params.getStatus())
                .eq(CardEntity::getId, params.getId())
                .update();
        if ("1".equals(params.getStatus())) {
            if (new LambdaQueryChainWrapper<>(snsAccountMapper).eq(SnsAccountEntity::getUid, params.getId()).count() == 0) {
                AccountInfo accountInfo = new AccountInfo();
                if (StringUtils.isNotBlank(cardEntity.getImages())) {
                    accountInfo.setAvatar(JSON.parseArray(cardEntity.getImages(), FileUploadDTO.class).get(0).getPreviewUrl());
                }
                accountInfo.setUid(params.getId());
                snsAccountService.add(accountInfo);
            }

        }
    }

    @Override
    public List<CardSameVO> sameClass(String position, String uid) {
        CardEntity cardEntity = new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getUid, uid).one();
        if (cardEntity == null || !"2".equals(cardEntity.getStatus())) {
            throw new RuntimeException("校友卡未申请或未通过审核");
        }
        List<CardSameVO> cardSameVOS = new ArrayList<>();
        MPJLambdaWrapper<CardEntity> wrapper = new MPJLambdaWrapper<>();
        if ("SameCity".equals(position)) {
            // 同城
            String area = null;
            if (StringUtils.isNotBlank(cardEntity.getWorkArea())) {
                String[] split = cardEntity.getWorkArea().split(",");
                String[] strings = Arrays.copyOfRange(split, 0, 2);
                area = StringUtils.join(strings, ",");
                wrapper.selectAll(CardEntity.class)
                        .selectAs(CrmUserEntity::getRealName, CardSameVO::getName)
                        .leftJoin(CrmUserEntity.class, CrmUserEntity::getId, CardEntity::getUid)
                        .like(StringUtils.isNotBlank(area), CardEntity::getWorkArea, area);
            }
        } else {
            StudentEntity studentEntity = new LambdaQueryChainWrapper<>(studentMapper)
                    .eq(StudentEntity::getUid, uid).eq(StudentEntity::getPosition, position).one();
            if (studentEntity != null) {
                wrapper.select(CardEntity::getPhone, CardEntity::getAvatar)
                        .select(StudentEntity::getName, StudentEntity::getGraduationClass, StudentEntity::getGraduationYear, StudentEntity::getPosition)
                        .innerJoin(StudentEntity.class, StudentEntity::getUid, CardEntity::getUid)
                        .eq(StudentEntity::getPosition, position)
                        .eq(StudentEntity::getGraduationYear, studentEntity.getGraduationYear())
                        .eq(StudentEntity::getGraduationClass, studentEntity.getGraduationClass());
            }
        }
        cardSameVOS = cardMapper.selectJoinList(CardSameVO.class, wrapper);
        return cardSameVOS;
    }

    @Override
    public boolean checkApply(String uid) {
        CardEntity entity = new LambdaQueryChainWrapper<>(cardMapper)
                .eq(CardEntity::getUid, uid)
                .eq(CardEntity::getStatus, "2")
                .one();
        return !(entity == null);
    }

    @Override
    public List<Map<String, Object>> getCount() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("title", "总人数");
        map1.put("count", cardMapper.selectCount(null));
        map1.put("icon", "el-icon-user-solid");
        map1.put("color", "rgb(49, 180, 141)");
//        map1.put("href", "https://avuejs.com");
//        map1.put("target", "_blank");
        list.add(map1);

        Map<String, Object> map2 = new HashMap<>();
        map2.put("title", "已申请");
        map2.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "2").count());
        map2.put("icon", "el-icon-postcard");
        map2.put("color", "rgb(56, 161, 242)");
//        map2.put("href", "https://avuejs.com");
//        map2.put("target", "_blank");
        list.add(map2);

        Map<String, Object> map3 = new HashMap<>();
        map3.put("title", "审核中");
        map3.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "1").count());
        map3.put("icon", "el-icon-setting");
        map3.put("color", "rgb(117, 56, 199)");
//        map3.put("href", "https://avuejs.com");
//        map3.put("target", "_blank");
        list.add(map3);

        Map<String, Object> map4 = new HashMap<>();
        map4.put("title", "未通过");
        map4.put("count", new LambdaQueryChainWrapper<>(cardMapper).eq(CardEntity::getStatus, "-1").count());
        map4.put("icon", "el-icon-setting");
        map4.put("color", "rgb(230, 71, 88)");
//        map4.put("href", "https://avuejs.com");
//        map4.put("target", "_blank");
        list.add(map4);

        return list;
    }

    @Override
    public List<CardDTO> getLocationCard() {
        MPJLambdaWrapper<CardEntity> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(CardEntity.class)
                .selectAll(CrmUserEntity.class)
                .leftJoin(CrmUserEntity.class, CrmUserEntity::getId, CardEntity::getUid)
                .eq(CardEntity::getStatus, "2")
                .and(w -> w.isNotNull(CardEntity::getCoordinate).or().ne(CardEntity::getCoordinate, ""));
        return cardMapper.selectJoinList(CardDTO.class, wrapper);
    }


}
